home *** CD-ROM | disk | FTP | other *** search
/ CDUTIL 13 / CDUTIL #13 Julio 1995.iso / windows / acadcom / ads / sample / arbmat.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-02-08  |  7.0 KB  |  277 lines

  1. /* Next available MSG number is   9 */
  2.  
  3. /*    
  4.  
  5.    ARBMAT.C
  6.  
  7.    Copyright (C) 1989, 1990, 1991, 1992, 1993, 1994 by Autodesk, Inc.
  8.  
  9.    Permission to use, copy, modify, and distribute this software in 
  10.    object code form for any purpose and without fee is hereby granted, 
  11.    provided that the above copyright notice appears in all copies and 
  12.    that both that copyright notice and the limited warranty and 
  13.    restricted rights notice below appear in all supporting 
  14.    documentation.
  15.  
  16.    AUTODESK PROVIDES THIS PROGRAM "AS IS" AND WITH ALL FAULTS.  
  17.    AUTODESK SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTY OF 
  18.    MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE.  AUTODESK, INC.
  19.    DOES NOT WARRANT THAT THE OPERATION OF THE PROGRAM WILL BE 
  20.    UNINTERRUPTED OR ERROR FREE.
  21.  
  22.    Use, duplication, or disclosure by the U.S. Government is subject to 
  23.    restrictions set forth in FAR 52.227-19 (Commercial Computer 
  24.    Software - Restricted Rights) and DFAR 252.227-7013(c)(1)(ii) 
  25.    (Rights in Technical Data and Computer Software), as applicable.
  26.     
  27.    .
  28.       DESCRIPTION:
  29.  
  30.       Prints out the axis of the entity coordinate system (ECS)
  31.       specified by the entity's X,Y and Z DXF fields.
  32.  
  33.       Usage: (arbmat X Y Z)
  34.  
  35.       where X,Y and Z are real numbers.
  36.  
  37.       For more information on ECS and the arbitrary axis  
  38.       algorithm see the AutoCAD Reference manual.
  39. */
  40.  
  41. #include <stdio.h>                    /* printf, sprintf, sscanf etc... */
  42. #include <math.h>                     /* for sqrt() */
  43. #include "adslib.h"
  44.  
  45. #define ExtFuncCount    1             /* Must increase this count if new 
  46.                                          external functions are added */
  47.  
  48. char *exfun[] = {/*MSG0*/"arbmat"};   /* No "C:" -- to be called as an AutoLISP
  49.                                          function, not as an AutoCAD command */
  50.  
  51. #define GOOD       0
  52. #define BAD        (-1)
  53.  
  54. #define ARBBOUND   0.015625           /*  1/64th  */
  55. #define EPS        (1E-10)
  56.  
  57. typedef double real;
  58. typedef real vec[3];
  59. typedef vec matrix[3];
  60.  
  61. void    main            _((int, char **));
  62. int     funcload        _((void));
  63. int     dofun           _((void));
  64. int     arbmat          _((matrix, vec));
  65. int     univec          _((vec, vec));
  66. real    rabs            _((real));
  67. void    cross           _((vec, vec, vec));
  68. void    prtaxis         _((char *, vec));
  69.  
  70.  
  71. void
  72. main(argc, argv)
  73.   int argc;
  74.   char *argv[];
  75.  
  76. {
  77.     int stat;
  78.     short scode = RSRSLT;             /* This is the default result code */
  79.     char errmsg[80];
  80.  
  81.     ads_init(argc, argv);             /* Initialize the interface */
  82.  
  83.     for ( ;; ) {                      /* Note loop conditions */
  84.  
  85.         if ((stat = ads_link(scode)) < 0) {
  86.             sprintf(errmsg,
  87.                     /*MSG1*/"ARBMAT: bad status from ads_link() = %d\n",
  88.                     stat);
  89.  
  90.             /* Can't use ads_printf to display 
  91.                this message, because the link failed */
  92. #ifdef Macintosh
  93.             macalert(errmsg);
  94. #else
  95.             puts(errmsg);
  96.             fflush(stdout);
  97. #endif /* Macintosh */
  98.             exit(1);
  99.         }
  100.  
  101.         scode = RSRSLT;               /* Default return value */
  102.  
  103.  
  104.         /* Check for AT LEAST the following cases here */
  105.  
  106.         switch (stat) {
  107.  
  108.         case RQXLOAD:                 /* Load & define functions */
  109.             scode = funcload() ? RSRSLT : -RSERR;
  110.             break;
  111.  
  112.         case RQSUBR:                  /* Handle external function request */
  113.             scode = dofun() ? RSRSLT: RSERR;
  114.             break;
  115.  
  116.         default:
  117.             break;
  118.         }
  119.     }
  120. }
  121. /*-----------------------------------------------------------------------*/
  122. /* FUNCLOAD  --  Define this application's external functions  */
  123.  
  124. int funcload()
  125. {
  126.     int i;
  127.     for (i = 0; i < ExtFuncCount; i++) {
  128.         if (!ads_defun(exfun[i], i))
  129.             return RTERROR;
  130.     }
  131.     return RTNORM;
  132. }
  133. /*-----------------------------------------------------------------------*/
  134. /* DOFUN -- Execute external function (called upon an RQSUBR request) */
  135.  
  136. int
  137. /*FCN*/dofun()
  138. {
  139.     struct resbuf *getargs = NULL, *rb = NULL;
  140.     int val;
  141.     matrix m;
  142.     vec zaxis;
  143.     int count = 0;                    /* counter for # of arguments */
  144.  
  145.     /* Get the required arguments */
  146.  
  147.     if ((getargs = ads_getargs()) == NULL)
  148.         return 0;
  149.  
  150.     /* Check the type and number of args */
  151.  
  152.     rb = getargs;
  153.     while (rb != NULL) {
  154.         if (rb->restype != RTREAL) {
  155.             ads_printf(/*MSG2*/"\nARBMAT called with type %d. ", rb->restype);
  156.             ads_printf(/*MSG3*/"\nERROR:  Arg. %d --  Real expected. ", count);
  157.             ads_relrb(getargs);
  158.             return 0;
  159.         }
  160.         zaxis[count] = rb->resval.rreal;
  161.         rb = rb->rbnext;
  162.         count++;
  163.     }
  164.  
  165.     /* Release the argument list */
  166.     ads_relrb(getargs);
  167.  
  168.     /* Make sure we have enough arguments after leaving while loop */
  169.     if (count < 2) {
  170.         ads_printf(/*MSG4*/"\n\
  171. ERROR: Arg. %d -- Insufficient number of argumenets.", count);
  172.         ads_printf(/*MSG5*/"\nUsage: (arbmat X Y Z)\n");
  173.         return 0;
  174.     }
  175.  
  176.     if ((val = ads_getfuncode()) < 0)
  177.         return 0;
  178.  
  179.     switch (val) {
  180.  
  181.     case 0:
  182.         prtaxis(/*MSG6*/"Input", zaxis);
  183.         ads_printf("\n");
  184.  
  185.         if (arbmat(m, zaxis) == BAD) {
  186.             ads_printf(/*MSG7*/"X, Y, or Z must be non zero.\n");
  187.         } else {
  188.             prtaxis(/*MSG0*/"X", m[X]);
  189.             prtaxis(/*MSG0*/"Y", m[Y]);
  190.             prtaxis(/*MSG0*/"Z", m[Z]);
  191.             ads_printf("\n");
  192.         }
  193.         break;
  194.     default:
  195.         break;
  196.     }
  197.  
  198.     ads_retvoid();
  199.  
  200. }
  201.  
  202.  
  203. int
  204. arbmat(m, zaxis)
  205.   matrix m;                           /* output matrix */
  206.   vec zaxis;                          /* X, Y, Z */
  207. {
  208.     static matrix ref = {{1.0, 0.0, 0.0}, {0.0, 1.0, 0.0}, {0.0, 0.0, 1.0}};
  209.  
  210.     if (univec(m[Z], zaxis) == BAD)
  211.         return (BAD);
  212.  
  213.     if (rabs(m[Z][X]) < ARBBOUND && rabs(m[Z][Y]) < ARBBOUND)
  214.         cross(m[X], ref[Y], m[Z]);
  215.     else
  216.         cross(m[X], ref[Z], m[Z]);
  217.  
  218.     univec(m[X], m[X]);
  219.  
  220.     cross(m[Y], m[Z], m[X]);
  221.     univec(m[Y], m[Y]);
  222.  
  223.     return (GOOD);
  224. }
  225.  
  226.  
  227. int
  228. univec(a, b)
  229.   vec a, b;
  230. {
  231.     real d;
  232.  
  233.     if ((d = (b[X] * b[X] + b[Y] * b[Y] + b[Z] * b[Z])) < EPS)
  234.         return (BAD);
  235.  
  236.     d = 1.0 / sqrt(d);
  237.  
  238.     a[X] = b[X] * d;
  239.     a[Y] = b[Y] * d;
  240.     a[Z] = b[Z] * d;
  241.     return (GOOD);
  242. }
  243.  
  244.  
  245. real
  246. rabs(a)
  247.   real a;
  248. {
  249.     return (a > 0.0 ? a : -a);
  250. }
  251.  
  252.  
  253. void
  254. cross(a, b, c)
  255.   vec a, b, c;
  256. {
  257.     a[X] = b[Y] * c[Z] - b[Z] * c[Y];
  258.     a[Y] = b[Z] * c[X] - b[X] * c[Z];
  259.     a[Z] = b[X] * c[Y] - b[Y] * c[X];
  260. }
  261.  
  262.  
  263. void
  264. prtaxis(s, a)
  265.   char *s;
  266.   vec a;
  267. {
  268.     int i;
  269.     char temp[50];
  270.  
  271.     ads_printf(/*MSG8*/"\n%s axis: ", s);
  272.     for (i = X; i <= Z; i++) {
  273.         sprintf(temp, "%f", a[i]);    /* printf can disagree with < 0.0 ! */
  274.         ads_printf("%s%f ", (temp[0] == '-') ? "" : "+", a[i]);
  275.     }
  276. }
  277.